<script setup lang="ts">
import {ref, Ref, onMounted, watch, PropType, nextTick} from 'vue';
import {Placement} from '../types/popover';
const props = defineProps({
    // 弹出层位置
    placement: {
        type: Object as PropType<Placement>,
        default: () => ( {hor: 'center', ver: 'center'} as Placement)
    }
});
// 弹出层元素
const popOverEl:Ref<HTMLElement|null> = ref(null);
const popOverContainerEl:Ref<HTMLElement|null> = ref(null);
const active:Ref<boolean> = ref(false);
// 获取内容位置
const getContentPos = () => {
    if(popOverEl.value){
        return popOverEl.value.getBoundingClientRect();
    }
    return null;
};
// 计算顶点位置
const calculateOriginPositiont = () => {
    const place = {left: 0, top: 0};
    const contentPos = getContentPos();
    if(contentPos){
        // 计算水平顶点位置
        switch(props.placement.hor){
            case 'left':
                place.left = contentPos.x;
                break;
            case 'right':
                place.left = contentPos.x + contentPos.width;
                break;
            case 'center':
                place.left = contentPos.x + contentPos.width / 2;
                break;
        }
        // 计算垂直顶点位置
        switch(props.placement.ver){
            case 'top':
                place.top = contentPos.y;
                break;
            case 'bottom':
                place.top = contentPos.y + contentPos.height;
                break;
            case 'center':
                place.top = contentPos.y + contentPos.height / 2;
                break;
        }

    }
    return place;
};

// 设置弹出层绒容器位置
const setContainerPos = () => {
    // 获取内容位置
    const contentPos = getContentPos();
    if(contentPos && popOverContainerEl.value){
        const originPlace = calculateOriginPositiont();
        popOverContainerEl.value.style.left = `${originPlace.left}px`;
        popOverContainerEl.value.style.top = `${originPlace.top}px`;
        // 修复位置, 防止超出屏幕
        const popOverContainerRect = popOverContainerEl.value.getBoundingClientRect();
        if(popOverContainerRect.right > window.innerWidth - 2){
            popOverContainerEl.value.style.left = `${window.innerWidth - popOverContainerRect.width - 2}px`;
        }
        if(popOverContainerRect.bottom > window.innerHeight - 2){
            popOverContainerEl.value.style.top = `${window.innerHeight- popOverContainerRect.height - 2}px`;
        }
    }
};
// 点击内容
const onPopOverContentClick = () => {
    active.value = !active.value;
};
watch(active, (active) => {
    if(active){
        nextTick(() => {
            setContainerPos();
        });
    }
});
onMounted(() => {
    window.addEventListener('resize', () => {
        if(active.value){
            setContainerPos();
        }
    });
});

</script>
<template>
	<div
		ref="popOverEl"
		class="nd-pop-over"
		@click="onPopOverContentClick"
	>
		<slot />
		<teleport to="body">
			<transition name="nd-pop-over-container">
				<div
					v-if="active"
					ref="popOverContainerEl"
					class="nd-pop-over-container"
				>
					<slot name="reference" />
				</div>
			</transition>
		</teleport>
	</div>
</template>